﻿using Furion.FriendlyException;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Furion.CMS.Core.Permission
{
    /// <summary>
    /// 权限定义上下文
    /// </summary>
    public class PermissionDefinitionContext : IPermissionDefinitionContext
    {
        /// <summary>
        /// 权限组
        /// </summary>
        public Dictionary<string, PermissionGroupDefinition> Groups { get; }

        /// <summary>
        /// 服务提供者
        /// </summary>
        public IServiceProvider ServiceProvider { get; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="serviceProvider">服务提供者</param>
        public PermissionDefinitionContext(IServiceProvider serviceProvider)
        {
            Groups = new Dictionary<string, PermissionGroupDefinition>();
            ServiceProvider = serviceProvider;
        }

        /// <summary>
        /// 添加权限组(根据传入的泛型类生成权限组代码)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="displayName"></param>
        /// <returns></returns>
        public PermissionGroupDefinition<T> AddGroup<T>(string displayName) where T : class
        {
            var type = typeof(T);
            var nameOriginal = type.Name;
            var displayNameAttr = type.GetCustomAttributes(typeof(DisplayNameAttribute), true).FirstOrDefault();
            if (displayNameAttr is DisplayNameAttribute attr && !string.IsNullOrWhiteSpace(attr.DisplayName))
            {
                nameOriginal = attr.DisplayName;
            }
            var groupDefinition = AddGroup(nameOriginal, displayName);
            return new PermissionGroupDefinition<T>(groupDefinition);
        }

        /// <summary>
        /// 添加组
        /// </summary>
        /// <param name="name"></param>
        /// <param name="displayName"></param>
        /// <returns></returns>
        public virtual PermissionGroupDefinition AddGroup(string name, string displayName)
        {
            // 统一对输入命名进行处理
            name = PermissionGroupDefinition.PermissionGroupNamed(name);

            if (Groups.ContainsKey(name))
            {
                throw Oops.Bah($"存在已存在的权限组名称,组名称{name}");
            }
            var group = new PermissionGroupDefinition(name, displayName);
            Groups.TryAdd(name, group);
            return group;
        }

        /// <summary>
        /// 获取组
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public virtual PermissionGroupDefinition GetGroup(string name)
        {
            return Groups.GetValueOrDefault(name);
        }

        /// <summary>
        /// 移除组
        /// </summary>
        /// <param name="name"></param>
        public virtual void RemoveGroup(string name)
        {
            Groups.Remove(name);
        }
    }
}
